package com.sakura.util.java.trycatch;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by apple on 2018/8/9.
 */
public class TestTryCatch {
    public static void main(String[] args) {
//        int result1 = testBasic();
//        System.out.println("result1:"+result1);
//
//        int result2 = testBasic2();
//        System.out.println("result2:"+result2);
//
//        List result3 = testWrap();
//        System.out.println("result3:"+result3.toString());

        int result4 = testBasic4();
        System.out.println("result4:"+result4);
    }

    public static  int testBasic(){
        int i = 1;
        try{
            i++;
            System.out.println("try block, i = "+i);
        }catch(Exception e){
            i ++;
            System.out.println("catch block i = "+i);
        }finally{
            i = 10;
            System.out.println("finally block i = "+i);
        }
        return i;
    }

    /**
     * 代码顺序执行从try到finally，由于finally是无论如何都会执行的，
     * 所以try里的语句并不会直接返回。在try语句的return块中，return返回的引用变量并不是try语句外定义的引用变量i,
     * 而是系统重新定义了一个局部引用i’，这个引用指向了引用i对应的值，也就是2，即使在finally语句中把引用i指向了值10，
     * 因为return返回的引用已经不是i,而是i',所以引用i的值和try语句中的返回值无关了。
     * @return
     */
    public static  int testBasic2(){
        int i = 1;
        try{
            i++;
            System.out.println("try block, i = "+i);
            return i;
        }catch(Exception e){
            i ++;
            System.out.println("catch block i = "+i);
            return i;
        }finally{
            i = 10;
            System.out.println("finally block i = "+i);
        }
    }

    /**
     * 可以看到，finally里对list集合的操作生效了，这是为什么呢。
     * 我们知道基本类型在栈中存储，而对于非基本类型是存储在堆中的，返回的是堆中的地址，因此内容被改变了。
     * @return
     */
    public static  List<Object> testWrap(){
        List<Object> list = new ArrayList<>();
        try{
            list.add("try");
            System.out.println("try block");
            return list;
        }catch(Exception e){
            list.add("catch");
            System.out.println("catch block");
            return list;
        }finally{
            list.add("finally");
            System.out.println("finally block ");
        }
    }

    /**
     * 可以看到，是从finally语句块中返回的。可见，JVM是忽略了try中的return语句。
     * 但IDE中会对finally中加的return有黄色警告提示
     * @return
     */
    public static  int testBasic4(){
        int i = 1;
        try{
            i++;
            System.out.println("try block, i = "+i);
            return i;
        }catch(Exception e){
            i ++;
            System.out.println("catch block i = "+i);
            return i;
        }finally{
            i = 10;
            System.out.println("finally block i = "+i);
            return i;
        }
    }
}
